package com.sky.module.suppot.file.service.impl;

import cn.hutool.core.io.file.FileNameUtil;
import com.amazonaws.SdkClientException;
import com.amazonaws.services.s3.model.PutObjectResult;
import com.sky.module.suppot.file.domain.entity.FileEntity;
import com.sky.module.suppot.file.s3.OssClient;
import com.sky.module.suppot.file.s3.OssProperties;
import com.sky.module.suppot.file.service.FileStorageService;
import com.sky.utils.Result;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FilenameUtils;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.support.RequestContextUtils;

import java.io.IOException;
import java.security.Security;
import java.time.LocalDateTime;
import java.util.UUID;

/**
 * @author
 * @date 2023/2/28 23:12
 **/
@Slf4j
//@Service
public class FileStorageServiceCloudImpl implements FileStorageService {
    @Autowired
    private OssClient ossClient;

    @Value("${oss.bucket-name}")
    private String bucketName;

    @Autowired
    private OssProperties ossProperties;

    /***
     * @description 文件上传
     * @param
     * @param path  文件夹名称
     * @return com.sky.utils.Result<?>  图片url， and 文件key 文件原始名称，文件大小，文件类型 上传人 上传时间
     * @date 2023/3/1 0:28
     *
     */
    @Override
    public Result<FileEntity> fileUpload(MultipartFile multipartFile, String path) {
        // 构建  文件存储路径
        String originalFilename = multipartFile.getOriginalFilename();
        String extension = FilenameUtils.getExtension(originalFilename);
        String newFileName = UUID.randomUUID().toString()
                .replace("-", "") + "." + extension;
        String datePath = new DateTime().toString("yyyy/MM/dd");
        newFileName = path + "/" + datePath + "/" + newFileName;
        String fileKey = newFileName; // 新文件名
        long beginTime = System.currentTimeMillis();
        try {
            final PutObjectResult putObjectResult = ossClient.putObject(bucketName, newFileName, multipartFile.getInputStream());
            log.info(fileKey + "文件正在上传");
        } catch (IOException e) {
            e.printStackTrace(); // 如果上传失败
//             就有可能是 没有通，就创建桶 然后再上传
            ossClient.createBucket(bucketName);
            try {
                PutObjectResult putObjectResult = ossClient.putObject(bucketName, newFileName, multipartFile.getInputStream());
            } catch (IOException ioException) {
                ioException.printStackTrace();
            }

//            TODO 设置桶的访问权限
//            ossClient.getS3Client().setBucketPolicy(bucketName, "public");
        }
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        String username = user.getUsername();
        long endTime = System.currentTimeMillis();
        log.info(fileKey + "文件上传完成");
        long consumptionTime = endTime - beginTime;
        log.info("消耗时间为" + (endTime - beginTime) + "毫秒");
        Long available = 0L;
        try {
            available = Long.valueOf(multipartFile.getInputStream().available());
        } catch (IOException e) {
            e.printStackTrace();
        }

        FileEntity fileEntity = FileEntity.builder().fileKey(fileKey)
                .fileSize(available)
                .fileName(originalFilename)
                .folderType(1)
                .fileType(FileNameUtil.getSuffix(originalFilename))
                .createTime(LocalDateTime.now())
                .storageType(ossProperties.getStorageType())
                .consumptionTime(consumptionTime)
                .creatorName(username)
                .build();
        // 访问地址， Endpoint 加上桶名称,  再加上 文件key
//        http://127.0.0.1:9000/ddddd/av.jpg
//        String ip = ossProperties.getEndpoint() + "/" + bucketName + "/"+ file
        //        上传完以后，要返回一些信息，然后前端再次发请求，保存对应的上传记录
//        final FileEntity fileEntity = FileEntity.builder().build();
        //  上传成功
        return Result.ok(fileEntity).message("上传成功");

    }


    @Override
    public Result<?> delete(String fileKey) {
        try {
            ossClient.getS3Client().deleteObject(bucketName, fileKey);
        } catch (SdkClientException e) {
            e.printStackTrace();
            return Result.error().message("删除失败");
        }
        return Result.ok().message("删除成功");


    }

    @Override
    public Result<String> getFileUrl(String fileKey) {
        String endpoint = ossProperties.getEndpoint();
        String url = endpoint + "/" + ossProperties.getBucketName() + "/" + fileKey;
        return Result.ok(url);
    }
}
